package com.weishu.upf.service_management.app.hook; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import android.content.ComponentName; import android.content.Intent; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import com.weishu.upf.service_management.app.ProxyService; import com.weishu.upf.service_management.app.ServiceManager; import com.weishu.upf.service_management.app.UPFApplication; /** * @author weishu * @dete 16/1/7. */ /* package */ class IActivityManagerHandler implements InvocationHandler { private static final String TAG = "IActivityManagerHandler"; Object mBase; public IActivityManagerHandler(Object base) { mBase = base; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("startService".equals(method.getName())) { // 只拦截这个方法 // API 23: // public ComponentName startService(IApplicationThread caller, Intent service, // String resolvedType, int userId) throws RemoteException // 找到参数里面的第一个Intent 对象 Pair<Integer, Intent> integerIntentPair = foundFirstIntentOfArgs(args); Intent newIntent = new Intent(); // 代理Service的包名, 也就是我们自己的包名 String stubPackage = UPFApplication.getContext().getPackageName(); // 这里我们把启动的Service替换为ProxyService, 让ProxyService接收生命周期回调 ComponentName componentName = new ComponentName(stubPackage, ProxyService.class.getName()); newIntent.setComponent(componentName); // 把我们原始要启动的TargetService先存起来 newIntent.putExtra(AMSHookHelper.EXTRA_TARGET_INTENT, integerIntentPair.second); // 替换掉Intent, 达到欺骗AMS的目的 args[integerIntentPair.first] = newIntent; Log.v(TAG, "hook method startService success"); return method.invoke(mBase, args); } // public int stopService(IApplicationThread caller, Intent service, // String resolvedType, int userId) throws RemoteException if ("stopService".equals(method.getName())) { Intent raw = foundFirstIntentOfArgs(args).second; if (!TextUtils.equals(UPFApplication.getContext().getPackageName(), raw.getComponent().getPackageName())) { // 插件的intent才做hook Log.v(TAG, "hook method stopService success"); return ServiceManager.getInstance().stopService(raw); } } return method.invoke(mBase, args); } private Pair<Integer, Intent> foundFirstIntentOfArgs(Object... args) { int index = 0; for (int i = 0; i < args.length; i++) { if (args[i] instanceof Intent) { index = i; break; } } return Pair.create(index, (Intent) args[index]); } }